package com.lanhao.aot.cosmic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import com.lanhao.aot.exchager.ExchangerUtil;

// 有个很重要的点 DemoDataListener 不能被spring管理，要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class DemoDataListener implements ReadListener<ParamModule> {

	private static final Logger log = LoggerFactory.getLogger(ExchangerUtil.class);

    static HashMap<String, String> mapDev1 = new HashMap() {{
        put("江青龙", "大模型应用研发人员");
        put("张圆", "大模型应用研发人员");
        put("尹小盼", "大模型应用研发人员");
    }};

    static HashMap<String, String> mapDev2 = new HashMap() {{
        put("高素伟", "大模型应用研发人员");
        put("何康杰", "大模型应用研发人员");
        put("亢振", "大模型应用研发人员");
    }};

    HashMap<String, String> mapDev3 = new HashMap() {{
        put("罗浩", "大模型应用研发人员");
        put("江青龙", "大模型应用研发人员");
        put("朱广勇", "大模型应用研发人员");
    }};
    
    HashMap<String, String> mapDev4 = new HashMap() {{
        put("江青龙", "大模型应用研发人员");
        put("张玉梅", "大模型应用研发人员");
        put("张圆", "大模型应用研发人员");
        put("何康杰", "大模型应用研发人员");

    }};

    HashMap<String, String> mapDev5= new HashMap() {{
        put("陶堃", "大模型应用研发人员");
        put("尹小盼", "大模型应用研发人员");
        put("罗浩", "大模型应用研发人员");
        put("亢振", "大模型应用研发人员");
    }};

    HashMap<String, String> mapDev6 = new HashMap() {{
        put("高素伟", "大模型应用研发人员");
        put("朱广勇", "大模型应用研发人员");
        put("汤洁泉", "大模型应用研发人员");
    }};

    /**
     * 缓存的数据
     */
    private List<ParamModule> cachedDataList = ListUtils.newArrayListWithExpectedSize(10000);

    private List<Requirement> result = new ArrayList<>();

    private ParamModule dataPre = new ParamModule();

    static Integer number = 0;
    /**
     * public DemoDataListener() {
     * // 这里是demo，所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
     * demoDAO = new DemoDAO();
     * }
     * <p>
     * <p>
     * /**
     * 这个每一条数据解析都会来调用
     *
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(ParamModule data, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        if (StringUtils.isNotBlank(data.getFunctionProcess())) {
            number++;
        }
        data.setNumber(number);
        if (StringUtils.isBlank(data.getModuleName())) {
            // 不是第一个
            data.setModuleName(dataPre.getModuleName());
        }
        if (StringUtils.isBlank(data.getFunctionProcess())) {
            data.setFunctionProcess(dataPre.getFunctionProcess());
        }
        cachedDataList.add(data);
        dataPre = data;
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        LinkedHashMap<Integer, List<ParamModule>> collect = cachedDataList.stream().collect(Collectors.groupingBy(ParamModule::getNumber, LinkedHashMap::new, Collectors.toList()));
        List<Requirement> list = new ArrayList<>();
        boolean flag = false;
        for (Map.Entry<Integer, List<ParamModule>> entry : collect.entrySet()) {
            Integer key = entry.getKey();
            List<ParamModule> paramModules = entry.getValue();
            StringBuilder str = new StringBuilder();
            for (ParamModule paramModule : paramModules) {
                str.append(paramModule.getSubProcessDescription()).append("\n");
            }
            if (StringUtils.contains(str.toString(), "用户输入个人话费金额")) {
                flag = true;
            }
            double sum = paramModules.stream().collect(Collectors.summarizingDouble(ParamModule::getCfpValue)).getSum();
            double day = sum * 4.11D;
            if (day == 0D){
                day = 0.3d;
            }
            if (flag) {
                // 1671之后对话 tyf
                list.add(getRandomScore(paramModules.get(0), str, mapDev1, 0.5, day));
                list.add(getRandomScore(paramModules.get(0), str, mapDev2, 0.2, day));
                list.add(getRandomScore(paramModules.get(0), str, mapDev3, 0.3, day));
            }else {
                //1671之前交互感知 jql
                list.add(getRandomScore(paramModules.get(0), str, mapDev4, 0.3, day));
                list.add(getRandomScore(paramModules.get(0), str, mapDev5, 0.6, day));
                list.add(getRandomScore(paramModules.get(0), str, mapDev6, 0.1, day));
            }
        }

        saveData(list);
        log.info("所有数据解析完成！");
    }


    /**
     * 加上存储数据库
     */
    private void saveData(List<Requirement> list) {
        log.info("{}条数据，开始存储数据库！", list.size());
        String fileName =   "D:\\testExcel合并.xlsx";
        EasyExcel.write(fileName, Requirement.class)
                .sheet()
                // 开启相等值 列合并,行合并,从行索引1(excel中第二行)开始合并, 指定跨行合并的列索引
                //.registerWriteHandler(new MergeCellStrategyHandler(true, true, 1, Set.of(0, 2, 4, 5)))

                // 开启相等值 列合并,从行索引1(excel中第二行)开始合并
                //.registerWriteHandler(new MergeCellStrategyHandler(true, 1))

                // 开启相等值 行合并,从行索引1(excel中第二行)开始合并, 指定跨行合并的列索引
                .registerWriteHandler(new MergeCellStrategyHandler(true, 1, Sets.newHashSet( 0,1, 2, 3,4,5,6,7,8,15),list.size()))
                .doWrite(list);
        log.info("存储数据库成功！");
    }
    private static Requirement getRandomScore(ParamModule paramModule, StringBuilder str, HashMap<String, String> mapDev, double ratio, double day) {

        // 随机选择一个成员
        String selectedMember = mapDev.keySet().toArray(new String[0])[new Random().nextInt(mapDev.size())];
        // 分配分数
        double  ceil = Math.ceil(day * ratio*10)/10.0;
        Requirement result = new Requirement();
        result.setNumber(paramModule.getNumber()+"");
        result.setProjName("销售分公司与科大讯飞股份有限公司关于中国移动APP应用系统大模型运营赋能研发（2024-2025）项目");
        result.setRequirementName(paramModule.getModuleName()+"-"+paramModule.getFunctionProcess());
        result.setRequirementDescription(str.toString()); //todo 模型润色
        result.setSupporterName(selectedMember);
        result.setSupportHours(ceil+"");

        result.setDepartment("中国移动通信有限公司销售分公司");
        result.setBusinessContact("杨斌哲");
        result.setProductManager("赵佳伟、屈凡、王焕丽");
        result.setStartDate("2024.07.24");
        result.setSupporterType("大模型应用研发人员");
        result.setProjectGroup("大模型支撑组");
        result.setPartner("科大讯飞");
        result.setPersonLevel("中级");
        result.setSxTrue("是");
        return result;
    }

}